/* AS3
   Copyright 2007 Jonathan Marston
 */
package com.waitingsnow.common.share.util
{

/**
 * Take a fileName, byteArray, and parameters object as input and return ByteArray post data suitable for a UrlRequest as output
 */

import com.adobe.images.JPGEncoder;
import com.adobe.images.PNGEncoder;

import flash.display.BitmapData;
import flash.utils.ByteArray;
import flash.utils.Endian;

public class UploadPostHelper
{

    public static const IMAGE_PNG:String = "iamge_png";

    public static const IMAGE_JPG:String = "image_jpg";

    //--------------------------------------
    //  PUBLIC METHODS
    //--------------------------------------

    /**
     * Boundary used to break up different parts of the http POST body
     */
    private static var _boundary:String = "";

    /**
     * Get the boundary for the post.
     * Must be passed as part of the contentType of the UrlRequest
     */
    public static function getBoundary():String
    {

        if (_boundary.length == 0)
        {
            for (var i:int = 0; i < 0x20; i++)
            {
                _boundary += String.fromCharCode(int(97 + Math.random() * 25));
            }
        }

        return _boundary;
    }

    /**
     * Create post data to send in a UrlRequest
     */

    //pictureBitmapData:BitmapData DisplayObject snap shoot or ImageSnapshot.captureBitmapData(DisplayObject);
    //parameters:Object eg. {myname:'test'}
    //fileDataName:String eg. 'preview[image]' with name "Filedata" default.
    //pictureType:String IMAGE_PNG/IMAGE_JPG

    public static function getPostData(pictureBitmapData:ByteArray,
                                       parameters:Object,
                                       fileDataName:String = "Filedata",
                                       pictureType:String = IMAGE_PNG):ByteArray
    {

        var fileName:String;
        var byteArray:ByteArray = pictureBitmapData;
        if (pictureType == IMAGE_PNG)
        {
            fileName = "temp.png";
        }
        else
        {
            fileName = "temp.jpg";
        }

        var i:int;
        var bytes:String;

        var postData:ByteArray = new ByteArray();
        postData.endian = Endian.BIG_ENDIAN;

        //add Filename to parameters
        if (parameters == null)
        {
            parameters = new Object();
        }
        parameters.Filename = fileName;

        //add parameters to postData
        for (var name:String in parameters)
        {
            postData = BOUNDARY(postData);
            postData = LINEBREAK(postData);
            bytes = 'Content-Disposition: form-data; name="' + name + '"';
            for (i = 0; i < bytes.length; i++)
            {
                postData.writeByte(bytes.charCodeAt(i));
            }
            postData = LINEBREAK(postData);
            postData = LINEBREAK(postData);
            postData.writeUTFBytes(parameters[name]);
            postData = LINEBREAK(postData);
        }

        //add Filedata to postData
        postData = BOUNDARY(postData);
        postData = LINEBREAK(postData);
        bytes = 'Content-Disposition: form-data; name="' + fileDataName + '"; filename="';
        for (i = 0; i < bytes.length; i++)
        {
            postData.writeByte(bytes.charCodeAt(i));
        }
        postData.writeUTFBytes(fileName);
        postData = QUOTATIONMARK(postData);
        postData = LINEBREAK(postData);
        bytes = 'Content-Type: image/jpeg';
        for (i = 0; i < bytes.length; i++)
        {
            postData.writeByte(bytes.charCodeAt(i));
        }
        postData = LINEBREAK(postData);
        postData = LINEBREAK(postData);
        postData.writeBytes(byteArray, 0, byteArray.length);
        postData = LINEBREAK(postData);

        //add upload filed to postData
        postData = LINEBREAK(postData);
        postData = BOUNDARY(postData);
        postData = LINEBREAK(postData);
        bytes = 'Content-Disposition: form-data; name="Upload"';
        for (i = 0; i < bytes.length; i++)
        {
            postData.writeByte(bytes.charCodeAt(i));
        }
        postData = LINEBREAK(postData);
        postData = LINEBREAK(postData);
        bytes = 'Submit Query';
        for (i = 0; i < bytes.length; i++)
        {
            postData.writeByte(bytes.charCodeAt(i));
        }
        postData = LINEBREAK(postData);

        //closing boundary
        postData = BOUNDARY(postData);
        postData = DOUBLEDASH(postData);
        return postData;
    }

    //--------------------------------------
    //  EVENT HANDLERS
    //--------------------------------------

    //--------------------------------------
    //  PRIVATE & PROTECTED INSTANCE METHODS
    //--------------------------------------

    /**
     * Add a boundary to the PostData with leading doubledash
     */
    private static function BOUNDARY(p:ByteArray):ByteArray
    {
        var l:int = UploadPostHelper.getBoundary().length;

        p = DOUBLEDASH(p);
        for (var i:int = 0; i < l; i++)
        {
            p.writeByte(_boundary.charCodeAt(i));
        }
        return p;
    }

    /**
     * Add one linebreak
     */
    private static function LINEBREAK(p:ByteArray):ByteArray
    {
        p.writeShort(0x0d0a);
        return p;
    }

    /**
     * Add quotation mark
     */
    private static function QUOTATIONMARK(p:ByteArray):ByteArray
    {
        p.writeByte(0x22);
        return p;
    }

    /**
     * Add Double Dash
     */
    private static function DOUBLEDASH(p:ByteArray):ByteArray
    {
        p.writeShort(0x2d2d);
        return p;
    }
}
}